package com.socialsoftware.MediaCommunication.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.media.audiofx.Visualizer;
import android.util.AttributeSet;
import android.view.View;

import java.util.Random;

/**
 * Custom view for audio visualization during calls
 */
public class AudioVisualizerView extends View {
    private static final int CAPTURE_SIZE = 256;
    private static final int LINE_WIDTH = 3;
    private static final int LINE_SCALE = 30;
    private static final int ANIMATION_INTERVAL = 50;

    private Paint linePaint;
    private Path path;
    private Random random;
    private byte[] audioBytes;
    private float[] points;
    private Visualizer visualizer;
    private boolean isActive = false;
    private boolean isSimulating = false;

    public AudioVisualizerView(Context context) {
        super(context);
        init();
    }

    public AudioVisualizerView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public AudioVisualizerView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        linePaint = new Paint();
        linePaint.setColor(Color.parseColor("#4CAF50")); // Green color
        linePaint.setStrokeWidth(LINE_WIDTH);
        linePaint.setAntiAlias(true);
        linePaint.setStyle(Paint.Style.STROKE);

        path = new Path();
        random = new Random();
        audioBytes = new byte[CAPTURE_SIZE];
        points = new float[CAPTURE_SIZE * 4];
    }

    /**
     * Link to audio session to visualize real audio
     */
    public void linkToAudioSession(int audioSessionId) {
        if (visualizer != null) {
            visualizer.release();
        }

        try {
            visualizer = new Visualizer(audioSessionId);
            visualizer.setCaptureSize(Visualizer.getCaptureSizeRange()[1]);
            
            visualizer.setDataCaptureListener(
                    new Visualizer.OnDataCaptureListener() {
                        @Override
                        public void onWaveFormDataCapture(Visualizer visualizer, byte[] bytes,
                                                          int samplingRate) {
                            updateVisualizer(bytes);
                        }

                        @Override
                        public void onFftDataCapture(Visualizer visualizer, byte[] bytes,
                                                     int samplingRate) {
                            // Not used
                        }
                    }, Visualizer.getMaxCaptureRate() / 2, true, false);
            
            visualizer.setEnabled(true);
            isActive = true;
            isSimulating = false;
        } catch (Exception e) {
            // Fall back to simulation if real visualization fails
            startSimulation();
        }
    }

    /**
     * Start simulating visualization when real audio can't be captured
     */
    public void startSimulation() {
        isSimulating = true;
        isActive = true;
        simulateAudioData();
    }

    /**
     * Update visualization with actual audio data
     */
    private void updateVisualizer(byte[] bytes) {
        if (!isActive) return;
        
        audioBytes = bytes;
        invalidate();
    }

    /**
     * Simulate audio data for visualization
     */
    private void simulateAudioData() {
        if (!isActive || !isSimulating) return;
        
        for (int i = 0; i < audioBytes.length; i++) {
            audioBytes[i] = (byte) (random.nextInt(80) - 40);
        }
        
        invalidate();
        postDelayed(this::simulateAudioData, ANIMATION_INTERVAL);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        
        if (audioBytes == null || !isActive) {
            return;
        }

        path.reset();
        
        float width = getWidth();
        float height = getHeight();
        float centerY = height / 2;
        float barWidth = width / (audioBytes.length - 1);
        
        // Draw waveform
        path.moveTo(0, centerY);
        
        for (int i = 0; i < audioBytes.length - 1; i++) {
            float x1 = i * barWidth;
            float y1 = centerY + ((byte) (audioBytes[i] + 128)) * (height / 256);
            float x2 = (i + 1) * barWidth;
            float y2 = centerY + ((byte) (audioBytes[i + 1] + 128)) * (height / 256);
            
            // Use quadratic bezier for smoother curves
            float midX = (x1 + x2) / 2;
            path.quadTo(x1, y1, midX, (y1 + y2) / 2);
        }
        
        canvas.drawPath(path, linePaint);
    }

    /**
     * Stop visualization and release resources
     */
    public void release() {
        isActive = false;
        isSimulating = false;
        
        if (visualizer != null) {
            visualizer.setEnabled(false);
            visualizer.release();
            visualizer = null;
        }
    }
    /**
     * Set the color of the visualizer
     */
    public void setColor(int color) {
        linePaint.setColor(color);
        invalidate();
    }
} 